package org.six11.olive3.picturephone.server.handler;

import java.io.File;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.ServletException;

import org.six11.olive3.net.Message;
import org.six11.olive3.net.MessageHandler;
import org.six11.olive3.net.OliveStreamHandler;
import org.six11.olive3.picturephone.server.PPMessageNames;
import org.six11.olive3.server.DatabaseThing;
import org.six11.olive3.server.SqlStrings;
import org.six11.util2.Debug;

/**
 * 
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class SketchRequestMessageHandler {

  public static String FAKE_PEN_MESSAGE = //
  "pen(user=\"1\") {\n" + //
      "  pt 212 68 t=\"1232311214189\"\n" + //
      "  pt 276 166 t=\"1232311214779\"\n" + //
      "  up t=\"1232311215067\"\n" + //
      "}";

  private static Random entropy = new Random(System.currentTimeMillis());
  private DatabaseThing db;

  public SketchRequestMessageHandler(DatabaseThing db) {
    this.db = db;
  }

  public boolean handle(String todoID, String sketchID, String uid, PrintWriter out) {
    boolean ret = false;
    Map<String, String> sketchData = null;
    Message sketchMessage = null;
    try {

      // Map<String, String> todoValues = db.getRow(SqlStrings.FIND_TODO_SKETCH_AT_LIMIT, uid, ""
      // + idx);

      if (sketchID != null) {
        sketchData = db.getRow(SqlStrings.FIND_SKETCH, sketchID);
        String messageStringFromDB = sketchData.get("data");
        if (messageStringFromDB == null || messageStringFromDB.length() == 0) {
          messageStringFromDB = FAKE_PEN_MESSAGE;
        }

        List<Message> messageFromDB = OliveStreamHandler
            .parseMessagesFromString(messageStringFromDB);
        if (messageFromDB.size() == 1) {
          sketchMessage = messageFromDB.get(0);
          sketchMessage.addParam(PPMessageNames.PARAM_SKETCH_ID, sketchID);
        }
        db.update(SqlStrings.DELETE_TODO_SKETCH, todoID);
        ret = true;
      }

    } catch (ServletException ex) {
      ex.printStackTrace();
    }
    if (sketchMessage != null) {
      out.write(sketchMessage.toOliveString());
      bug("Gave sketch data for sketch number "
          + sketchMessage.getParamValue(PPMessageNames.PARAM_SKETCH_ID));
    } else {
      Message error = new Message(PPMessageNames.MSG_ERROR);
//      error.addParam(PPMessageNames.PARAM_TEXT,
//          "Could not find any more available sketches for user " + uid + ". Sorry. " + //
//              "This means you have drawn verything that you can based on the descriptions in " + //
//              "the PicturePhone database. More likely than not this is an error and you " + //
//              "should email Gabe (johnsogg@cmu.edu). But if you play all the time it might " + //
//              "be legitimate. I dunno.");
//      out.write(error.toOliveString());
//      bug("Did not find anything. Sent an error message.");
    }
    return ret;
  }

  public void handleNowButNotQuite(Message m, PrintWriter out) {
    String uid = m.getParamValue(PPMessageNames.PARAM_USER_ID);
    Map<String, String> sketchData = null;
    Message sketchMessage = null;
    try {
      int howMany = db.getInt(SqlStrings.COUNT_TODO_SKETCH, uid);
      if (howMany > 0) {
        int idx = entropy.nextInt(howMany);
        Map<String, String> todoValues = db.getRow(SqlStrings.FIND_TODO_SKETCH_AT_LIMIT, uid, ""
            + idx);

        // todoValues = db.getRow(SqlStrings.FIND_TODO_SKETCH, uid);
        String luckySketchID = todoValues.get("sketch_id");
        if (luckySketchID != null) {
          sketchData = db.getRow(SqlStrings.FIND_SKETCH, luckySketchID);
          String messageStringFromDB = sketchData.get("data");
          if (messageStringFromDB == null || messageStringFromDB.length() == 0) {
            messageStringFromDB = FAKE_PEN_MESSAGE;
          }

          List<Message> messageFromDB = OliveStreamHandler
              .parseMessagesFromString(messageStringFromDB);
          if (messageFromDB.size() == 1) {
            sketchMessage = messageFromDB.get(0);
            sketchMessage.addParam(PPMessageNames.PARAM_SKETCH_ID, luckySketchID);
          }
          db.update(SqlStrings.DELETE_TODO_SKETCH, todoValues.get("id"));
        }
      }
    } catch (ServletException ex) {
      ex.printStackTrace();
    }
    if (sketchMessage != null) {
      out.write(sketchMessage.toOliveString());
      bug("Gave sketch data for sketch number "
          + sketchMessage.getParamValue(PPMessageNames.PARAM_SKETCH_ID));
    } else {
      Message error = new Message(PPMessageNames.MSG_ERROR);
      error.addParam(PPMessageNames.PARAM_TEXT,
          "Could not find any more available sketches for user " + uid + ". Sorry. " + //
              "This means you have drawn verything that you can based on the descriptions in " + //
              "the PicturePhone database. More likely than not this is an error and you " + //
              "should email Gabe (johnsogg@cmu.edu). But if you play all the time it might " + //
              "be legitimate. I dunno.");
      out.write(error.toOliveString());
      bug("Did not find anything. Sent an error message.");
    }
  }

  public void handleNowIsh(Message m, PrintWriter out) {
    String uid = m.getParamValue(PPMessageNames.PARAM_USER_ID);
    Map<String, String> sketchData = null;
    List<Integer> currentOK;
    List<Integer> bad;
    Message sketchMessage = null;
    try {
      currentOK = db.getIDs(SqlStrings.FIND_SKETCHES_NOT_BY_USER, uid);
      String okString = db.idListToCommaString(currentOK);
      String sql = db.setParameterDirectly(SqlStrings.FIND_SKETCHES_BY_USER_DISQUALIFY_CHILDREN,
          okString, 2);
      bad = db.getIDs(sql, uid);
      String badString = db.idListToCommaString(bad);
      currentOK.removeAll(bad);
      okString = db.idListToCommaString(currentOK);
      sql = db.setParameterDirectly(SqlStrings.FIND_SKETCHES_BY_USER_DISQUALIFY_PARENTS, okString,
          2);
      bad = db.getIDs(sql, uid);
      badString = db.idListToCommaString(bad);
      currentOK.removeAll(bad);
      okString = db.idListToCommaString(currentOK);
      if (currentOK.size() > 0) {
        String luckySketchID = "" + currentOK.get(entropy.nextInt(currentOK.size()));
        sketchData = db.getRow(SqlStrings.FIND_SKETCH, luckySketchID);
        String messageStringFromDB = sketchData.get("data");
        List<Message> messageFromDB = OliveStreamHandler
            .parseMessagesFromString(messageStringFromDB);
        if (messageFromDB.size() == 1) {
          sketchMessage = messageFromDB.get(0);
          sketchMessage.addParam(PPMessageNames.PARAM_SKETCH_ID, luckySketchID);
        }
      }
    } catch (ServletException ex) {
      ex.printStackTrace();
    }
    if (sketchMessage != null) {
      out.write(sketchMessage.toOliveString());
      bug("Gave sketch data for sketch number "
          + sketchMessage.getParamValue(PPMessageNames.PARAM_SKETCH_ID));
      bug("Incidentally the message sig is '" + sketchMessage.getSignature() + "'");
    } else {
      Message error = new Message(PPMessageNames.MSG_ERROR);
      error.addParam(PPMessageNames.PARAM_TEXT,
          "Could not find any more available sketches for user " + uid + ". Sorry. " + //
              "This means you have drawn verything that you can based on the descriptions in " + //
              "the PicturePhone database. More likely than not this is an error and you " + //
              "should email Gabe (johnsogg@cmu.edu). But if you play all the time it might " + //
              "be legitimate. I dunno.");
      out.write(error.toOliveString());
      bug("Did not find anything. Sent an error message.");
    }
  }
  
  private void bug(String what) {
    Debug.out("SketchRequestMessageHandler", what);
  }
}
